﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LiveSequence.Common.Context;
using LiveSequence.Common;
using LiveSequence.Common.Presentation;
using LiveSequence.Common.Graphics;
using LiveSequence.Suite.Dialogs;
using LiveSequence.Suite.Documents;
using LiveSequence.Suite.Domain;
using LiveSequence.Suite.Interfaces;
using System.Windows;
using LiveSequence.Common.Domain;

namespace LiveSequence.Suite.Views
{
  public partial class DiagramView : BaseView<SeqDiagramDoc>
  {
    private DocManager _docManager;

    public DiagramView()
    {
      InitializeComponent();
      InitializeComponentEx();

      base._toolStrip = _diagramViewerToolStrip;
      _docManager = DocManager.Instance;
      _docManager.ActiveDocumentChanged += new EventHandler(_docManager_ActiveDocumentChanged);

      
      
      UpdateView(null);
      
    }

    private void InitializeComponentEx()
    {
      
    }

    void _docManager_ActiveDocumentChanged(object sender, EventArgs e)
    {
      SeqDiagramDoc seqDiagramDoc = _docManager.ActiveDocument as SeqDiagramDoc;

      if(seqDiagramDoc!=null)
      {
        SelectedDocument = seqDiagramDoc;
      }
    }

    public void Print(System.Windows.Controls.PrintDialog printDialog)
    {
      using (ContextHelper.CreatePrintScope(_diagramViewer, printDialog))
      {
        // Print scope will print out the file to the appropriate printer.
        // no further processing necessary at this point (for now).
        Logger.Current.Info(string.Format("Diagram printed to {0}", printDialog.PrintQueue.FullName));
      }

    }

    bool _bIsDirtyData;
    public bool IsDirtyData
    {
      get { return _bIsDirtyData; }
      set
      {
        _bIsDirtyData =value;
        OnIsDirtyDataChanged();
      }
    }

    private void OnIsDirtyDataChanged()
    {
      if (IsDirtyData)
      {
        _tsbtnRefresh.BackColor = Color.Red;
      }
      else
      {
        _tsbtnRefresh.BackColor = System.Drawing.SystemColors.Control;
      }
    }

    public override void UpdateView(object obj)
    {
      if (SelectedDocument != null)
      {
        IsDirtyData = true;
        LSMethodCallDiagram diagram = SelectedDocument.Diagram;
        if ((diagram != null) && (_tsbtnAutoRefresh.Checked))
        {
          renderDiagram(diagram);
        }
        _txtMethod.Text = string.Format("{0}/{1}", diagram.MethodData.TypeName,
                                        diagram.MethodData.MethodName);
      }
    }

    private void renderDiagram(LSMethodCallDiagram diagram)
    {
      _lblMethodDescription.Text = diagram.MethodData.MethodName;
      _lblSelectedAssembly.Text = diagram.MethodData.AssemblyName;
      _lblTypeName.Text = diagram.MethodData.TypeName;

      bool bRender = true;
      if(countVisibleMethods(diagram.SequenceData)> 100)
      {
        DialogResult result= System.Windows.Forms.MessageBox.Show("Visible method exceeds 100. Do you want to continue?",
                                             System.Windows.Forms.Application.ProductName, 
                                             MessageBoxButtons.OKCancel);
        if(result == DialogResult.Cancel)
        {
          bRender = false;
        }
      }

      if (bRender)
      {
        IRenderer renderer = new WPFRenderer();
        renderer.Export(diagram.SequenceData);
        IsDirtyData = false;
      }
    }

    private int countVisibleMethods(LiveSequence.Common.Domain.SequenceData sequenceData)
    {
      int iResult = 0;
      List<MethodCallInfo> methodList = sequenceData.GetMethodList();
      foreach(MethodCallInfo method in methodList)
      {
        iResult += method.Visible ? 1 : 0;
      }
      return iResult;
    }

    private void _tsbtnRefresh_Click(object sender, EventArgs e)
    {
			if (SelectedDocument != null)
			{
				LSMethodCallDiagram diagram = SelectedDocument.Diagram;
				if (diagram != null)
				{
					renderDiagram(diagram);
				}
			}
    }

    private void _tsbtnExport_Click(object sender, EventArgs e)
    {
      string strTargetFileName = string.Empty;
      SaveFileDialog dlg = new SaveFileDialog();
      dlg.Filter = "TIFF (*.tiff)|*.tiff|BMP (*.bmp)|*.bmp|PNG (*.png)|*.png|XPS-document (*.xps)|*.xps";
      if (dlg.ShowDialog() == DialogResult.OK)
      {
        strTargetFileName = dlg.FileName;
        using (ContextHelper.CreateSaveScope(_diagramViewer, strTargetFileName))
        {
          // Print scope will print out the file to the appropriate printer.
          // no further processing necessary at this point (for now).
          Logger.Current.Info(string.Format("Diagram printed to {0}", strTargetFileName));
        }
      }



    }

    private void copyTextTSMnuItem_Click(object sender, EventArgs e)
    {
      string strFormat = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang3082{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft Sans Serif;}}"
                         + "\\viewkind4\\uc1\\pard\\f0\\fs30 " + _lblMethodDescription.Text + "\\par"
                         + "\\i\\fs16 " + _lblTypeName.Text + "\\par "
                         + _lblSelectedAssembly.Text
                         + "\\i0\\fs17\\par"
                         + "}";


      System.Windows.Forms.Clipboard.SetData(System.Windows.Forms.DataFormats.Rtf, strFormat);
    }

    private void _btnSelectDiagram_Click(object sender, EventArgs e)
    {
      DlgMethodSelector dlgMethodSelector = new DlgMethodSelector();
      DialogResult result = dlgMethodSelector.ShowDialog();
      if(result == DialogResult.OK)
      {
        MethodData methodData = dlgMethodSelector.MethodData;
        SequenceData seqData = AssemblyExplorer.Instance.GetSequenceData(methodData.MethodName, 
                                                  methodData.TypeName, 
                                                  methodData.NamespaceText,
                                                  methodData.AssemblyName);
        SelectedDocument.SetData(methodData, seqData);


      }


    }

    protected override void OnSelectedDocumentChanged()
    {
      base.OnSelectedDocumentChanged();

      UpdateView(null);
    }


    
  }
}
